package com.icw.configuration;

import java.lang.reflect.Modifier;
import java.util.Set;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.stereotype.Component;

import com.icw.basis.BaseGeneric;
import com.icw.basis.BaseInterface;
import com.icw.basis.BasePoEntity;
import com.icw.utility.BeanCtxUtils;
import com.icw.utility.ClassUtil;
import com.icw.utility.EnvUtils;
import com.icw.utility.IcwUtils;

@Component
public final class ResourceModuleLoader implements Ordered, InitializingBean {

	// Those beans are no use here but need to be initialized the earliest;
	@SuppressWarnings("unused")
	@Autowired
	private BeanCtxUtils a;

	@SuppressWarnings("unused")
	@Autowired
	private HibernateTemplate b;

	@SuppressWarnings("unused")
	@Autowired
	private EnvUtils c;

	@SuppressWarnings("unchecked")
	public static void load() {
		IcwUtils.tryCatch(() -> {
			for (Class<?> moduleClass : ClassUtil.getClasses(ConstSettings.RESOURCE_MODULE_PACKAGE)) {
				BaseGeneric.createModule(moduleClass);
			}
			Set<Class<?>> infcs = ClassUtil.getClasses(ConstSettings.MODULE_INFC_PACKAGE);
			for (Class<?> entityClass : IcwUtils.getAllEntities()) {
				if (true// e
						&& BasePoEntity.class.isAssignableFrom(entityClass) // e
						&& Modifier.isPublic(entityClass.getModifiers())// e
				) {
					for (Class<?> inf : infcs) {
						if (BaseInterface.class.isAssignableFrom(inf)) {
							Class<? extends BaseInterface> infc = (Class<? extends BaseInterface>) inf;
							if (BaseGeneric.beanOf(infc, entityClass) == null) {
								BaseGeneric.createModule(infc, (Class<? extends BasePoEntity>) entityClass);
							}
						}
					}
				}
			}
		});
	}

	@Override
	public int getOrder() {
		return ConstSettings.FIRST_ORDER;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		load();
	}
}
